"use strict";

const path = require("path");
const fs = require("fs");
const Ps = require("ee-core/ps");
const { spawn } = require("child_process");
const { Service } = require("ee-core");
const logger = require("ee-core/log");
const ConfigManager = require("../config/engineManager")

const _configManager = new  ConfigManager();
// const is = require("electron-is")

// import is from 'electron-is'
const {
  getEnginePidPath,
  getAria2BinPath,
  getAria2ConfPath,
  getSessionPath,
  transformConfig,
} = require("../shared/utils/engine");

const { platform, arch } = process;

/**
 * 引擎服务（service层为单例）
 * @class
 */
class EngineService extends Service {
  static instance = null;

  constructor(ctx) {
    super(ctx);
  }

  /**
   * test
   */
  async start(args) {
    const pidPath = getEnginePidPath();
    logger.info("XDown Engine pid path :", pidPath);
    if (this.instance) {
      return;
    }

    const binPath = this.getEngineBinPath();
    const ariaArgs = this.getStartArgs();
    this.instance = spawn(binPath, ariaArgs, {
      windowsHide: false,
      stdio: Ps.isDev() ? "pipe" : "ignore",
    });
    const pid = this.instance.pid.toString();
    // 写入PID
    this.writePidFile(pidPath, pid);
    this.instance.once("close", () => {
      try {
        unlink(pidPath, (err) => {
          if (err) {
            logger.warn(`[XDown] 取消关联引擎pid文件失败: ${err}`);
          }
        });
      } catch (err) {
        logger.warn(`[XDown] 取消关联引擎pid文件失败: ${err}`);
      }
    });

    if (Ps.isDev()) {
      this.instance.stdout.on("data", (data) => {
        if(data){
          logger.info("[XDown] engine stdout===>", data.toString());
        }
      });
      // this.instance.stderr.on("data", (data) => {
      //   if(data){
      //     logger.info("[XDown] engine stderr===>", data.toString());
      //   }
      // });
    }
  }

  stop() {
    logger.info("[XDown] engine.stop.instance");
    if (this.instance) {
      this.instance.kill();
      this.instance = null;
    }
  }

  isRunning(pid) {
    try {
      return process.kill(pid, 0);
    } catch (e) {
      return e.code === "EPERM";
    }
  }

  restart() {
    this.stop();
    this.start();
  }

  writePidFile(pidPath, pid) {
    fs.writeFile(pidPath, pid, (err) => {
      if (err) {
        logger.error(`[XDown] 写入引擎PID失败: ${err}`);
      }
    });
  }

  // 判断启动路径
  getEngineBinPath() {
    const result = getAria2BinPath(platform, arch);
    const binIsExist = fs.existsSync(result);
    if (!binIsExist) {
      logger.error("[XDown] 引擎文件未找到:", result);
      throw new Error("引擎文件未找到");
    }

    return result;
  }

  // 启动参数
  getStartArgs() {
    // 获取配置
    const confPath = getAria2ConfPath(platform, arch);
    const sessionPath = getSessionPath();
    const sessionIsExist = fs.existsSync(sessionPath);

    let result = [`--conf-path=${confPath}`, `--save-session=${sessionPath}`];
    if (sessionIsExist) {
      result = [...result, `--input-file=${sessionPath}`];
    }
    const extraConfig = {
      ...this.systemConfig,
    };
    // logger.info('getStartArgs', _configManager.systemConfig.getItem("system")["seed-ratio"], _configManager.userConfig.getItem("user")["keep-seeding"])
    const keepSeeding = _configManager.userConfig.getItem("user")["keep-seeding"];
    const seedRatio = _configManager.systemConfig.getItem("system")["seed-ratio"];
    if (keepSeeding || seedRatio === 0) {
      extraConfig["seed-ratio"] = 0;
      delete extraConfig["seed-time"];
    }
    // console.log("extraConfig===>", extraConfig);

    const extra = transformConfig(extraConfig);
    result = [...result, ...extra];
    logger.info('result', result)
    return result;
  }
}

EngineService.toString = () => "[class EngineService]";
module.exports = EngineService;
